package models

import javax.inject.{Inject, Singleton}
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.jdbc.JdbcProfile

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext, Future}

@Singleton
class KeyValueRepository @Inject()( protected val dbConfigProvider: DatabaseConfigProvider)(implicit executionContext: ExecutionContext)
  extends HasDatabaseConfigProvider[JdbcProfile]  {
//  private val dbConfig = dbConfigProvider.get[JdbcProfile]

  import dbConfig._
  import profile.api._

  private class KeyValueTable(tag: Tag) extends Table[KeyValue](tag, "TEMP_KEYVALUE") {
    def id = column[Option[Int]]("id".toUpperCase, O.PrimaryKey, O.AutoInc)

    def kvKey = column[String]("kvKey".toUpperCase)

    def kvValue = column[String]("kvValue".toUpperCase)

    def kvTS = column[Long]("kvTS".toUpperCase)

    def * = (id, kvKey, kvValue, kvTS).<>((KeyValue.apply _).tupled, KeyValue.unapply)
  }

  private val kv = TableQuery[KeyValueTable]

  def list: Future[Seq[KeyValue]] = db.run {
    kv.result
  }

  def findByKey(key: String) = {
    //    val a = kvTable.filter(_.kvKey===key)
    val a = for (c <- kv if c.kvKey === key) yield c
    db.run(a.result)
  }

  def insert(keyvalue: KeyValue) = db.run{
    (kv returning kv.map(_.id)) += keyvalue
  }

  def update(keyvalue: KeyValue) = db.run{
    kv.filter(_.kvKey === keyvalue.vKey).map(f => (f.kvValue,f.kvTS)).update((keyvalue.vValue,keyvalue.vTimestamp))
  }

  def findBy(inputKey: String) = {
    val f = kv.filter(_.kvKey === inputKey).map(f => f).result
    Await.result(db.run(f),Duration.Inf)
  }

}
